import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpException,
  HttpStatus,
  Logger,
} from '@nestjs/common';
import { Request, Response } from 'express';
import { BusinessException } from '../exceptions/business.exception';
import { ErrorCode } from '../constants/error-code.enum';

/**
 * HTTP 异常过滤器
 * 捕获所有 HTTP 异常并统一格式化
 */
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  private readonly logger = new Logger(HttpExceptionFilter.name);

  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();
    const status = exception.getStatus();

    // 获取异常响应
    const exceptionResponse: any = exception.getResponse();

    // 判断是否为业务异常
    const isBusinessException = exception instanceof BusinessException;

    // 构建响应数据
    const responseData = {
      code: isBusinessException
        ? exceptionResponse.code
        : this.mapHttpStatusToErrorCode(status),
      message: isBusinessException
        ? exceptionResponse.message
        : this.getErrorMessage(exceptionResponse),
      data: null,
      timestamp: Date.now(),
      path: request.url,
    };

    // 记录错误日志（非业务异常才记录）
    if (!isBusinessException) {
      this.logger.error(
        `[${request.method}] ${request.url}`,
        JSON.stringify({
          status,
          message: responseData.message,
          stack: exception.stack,
          body: request.body,
          query: request.query,
          params: request.params,
        }),
      );
    }

    // 返回响应
    response.status(status).json(responseData);
  }

  /**
   * 将 HTTP 状态码映射为错误码
   */
  private mapHttpStatusToErrorCode(status: number): ErrorCode {
    const statusToErrorCode: Record<number, ErrorCode> = {
      [HttpStatus.BAD_REQUEST]: ErrorCode.BAD_REQUEST,
      [HttpStatus.UNAUTHORIZED]: ErrorCode.UNAUTHORIZED,
      [HttpStatus.FORBIDDEN]: ErrorCode.FORBIDDEN,
      [HttpStatus.NOT_FOUND]: ErrorCode.NOT_FOUND,
      [HttpStatus.TOO_MANY_REQUESTS]: ErrorCode.TOO_MANY_REQUESTS,
      [HttpStatus.INTERNAL_SERVER_ERROR]: ErrorCode.INTERNAL_SERVER_ERROR,
    };

    return statusToErrorCode[status] || ErrorCode.INTERNAL_SERVER_ERROR;
  }

  /**
   * 获取错误消息
   */
  private getErrorMessage(exceptionResponse: any): string {
    if (typeof exceptionResponse === 'string') {
      return exceptionResponse;
    }

    if (exceptionResponse.message) {
      // 处理验证错误
      if (Array.isArray(exceptionResponse.message)) {
        return exceptionResponse.message.join(', ');
      }
      return exceptionResponse.message;
    }

    return '请求失败';
  }
}



